from fastapi import APIRouter, Body, Depends
from peewee_async import Manager

from common.g.g import G_REDIS
from common.route.mall_route import MallMatchAPIRoute
from common.route.route import ZipCustomerRoute
from common.route.tenant_route import TenantBaseAPIRoute
from common.utils.depends.common import (
    get_mall_id,
    get_mgw,
    get_request_id
)
from common.utils.lock.lock import add_red_lock_once
from common.utils.resp import JsonResponse, RC
from common.v.v import CACHE_STOCK
from common.pkg.fastapi_util import cbv
from core.view import TenantBaseView
from enums.spu_enum import SPUSKUOnSaleEnum
from schema.req_schema.stock_req_schema import AddNewSPUStockModel
from service.spu_service import SPUService, StockService


router = APIRouter(prefix="/stock", route_class=ZipCustomerRoute(TenantBaseAPIRoute, MallMatchAPIRoute), tags=["stock"])


@cbv(router)
class StockView(TenantBaseView):

    @router.get("/spu/{spu_id:int}", description="获取单个spu的所有库存信息")
    async def get_spu_stock_detail(self, spu_id: int):
        ss = StockService(self.mgw, self.redis)
        ok, data_or_code = await ss.get_stock_detail_by_spu(self.mall_id, spu_id)
        if not ok:
            return JsonResponse(code=data_or_code.code, msg=data_or_code.msg).to_response()
        data = dict()
        data["mall_id"] = self.mall_id
        data["spu_id"] = spu_id
        data["stock_type"] = data_or_code.data["stock_type"]
        data["stock_list"] = [{"stock": v, "sku_id": k} for k, v in data_or_code.data["stock_info"].items()]
        return JsonResponse(data=data).to_response()

    @router.post("/spu/{spu_id:int}", description="设置spu的库存信息 其实就是批量设置/批量更新, 批量更新会将旧数据清除")
    async def add_spu_stock_info(self,
                                 spu_id: int,
                                 stock_model: AddNewSPUStockModel = Body(...),
                                 ):
        # 1.校验spu是否存在
        spu_s = SPUService(self.mgw, self.redis)
        spu_info = await spu_s.get_spu_detail(self.mall_id, spu_id, fields=["onsale"])
        if not spu_info:
            return JsonResponse(code=RC.NOT_EXIST, msg=f"商品:{spu_id}不存在").to_response()
        if spu_info.get("onsale") == SPUSKUOnSaleEnum.onsale:
            return JsonResponse(code=RC.FORBIDDING, msg=f"当前商品:{spu_id}处于上架状态,不允许编辑库存信息")
        # 设置当前spu库存信息的锁 10s内才允许操作相同spu一次 避免出现设置库存重复问题
        ok = await add_red_lock_once(self.redis, CACHE_STOCK.SET_SPU_STOCK_LOCK.format(spu_id=spu_id), self.request_id, 10)
        if not ok:
            return JsonResponse(code=RC.RATE_LIMIT, msg="请求过快,请稍后再试").to_response()
        ss = StockService(self.mgw, self.redis)
        ok, data_or_code = await ss.set_stock(self.mall_id, spu_id, stock_model)
        return self.unpack_response(ok, data_or_code)

    @router.get("/spu/{spu_id:int}/sku/{sku_id}", description="获取单个sku的库存信息")
    async def get_spu_sku_stock_detail(self, spu_id: int, sku_id: int):
        # 1. 判断spu和sku是否存在
        # 2. 获取库存信息
        ss = StockService(self.mgw, self.redis)
        ok, data_or_code = await ss.get_stock_detail_by_sku(self.mall_id, spu_id, sku_id)
        return self.unpack_response(ok, data_or_code)


    @router.post("/spu/{spu_id:int}/sku/{sku_id:int}", description="设置单个sku的库存信息")
    async def add_spu_sku_stock_info(self):
        ...


    @router.put("/spu/{spu_id:int}/sku/{sku_id:int}", description="修改单个sku的库存信息")
    async def update_spu_sku_stock_info(self):
        ...


    @router.delete("/spu/{spu_id:int}/sku/{sku_id:int}/item/{id:int}", description="删除sku的库存信息，指某一条库存信息")
    async def delete_stock_by_stock_item_id(self, spu_id: int, sku_id: int, id: int):
        ...


    @router.put("/spu/{spu_id:int}/sku/{sku_id:int}/item/{id:int}", description="更新sku的库存信息，指某一条库存信息")
    async def update_stock_by_stock_item_id(self, spu_id: int, sku_id: int, id: int):
        ...

